package com.x.attendance.assemble.control.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.x.attendance.core.entity.AttendanceDevice;
import com.x.attendance.core.entity.AttendanceRecord;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;

/**
 * 考勤数据采集服务
 * @author Manus AI
 */
public class AttendanceDataService {

	private static Logger logger = LoggerFactory.getLogger(AttendanceDataService.class);
	
	private AttendanceDeviceService deviceService;

	public AttendanceDataService() {
		this.deviceService = new AttendanceDeviceService();
	}

	/**
	 * 从设备采集考勤记录
	 */
	public List<AttendanceRecord> collectRecordsFromDevice(AttendanceDevice device) {
		List<AttendanceRecord> records = new ArrayList<>();
		
		try {
			// 连接设备
			boolean connected = deviceService.connectDevice(device.getIpAddress(), device.getPort());
			if (!connected) {
				logger.error("连接设备失败: " + device.getName());
				return records;
			}

			// 下载考勤记录
			List<RawAttendanceRecord> rawRecords = deviceService.downloadAttendanceRecords();
			
			// 转换为系统记录格式
			for (RawAttendanceRecord rawRecord : rawRecords) {
				AttendanceRecord record = convertToAttendanceRecord(rawRecord, device);
				if (record != null) {
					records.add(record);
				}
			}

			// 断开连接
			deviceService.disconnect();
			
			logger.info("从设备采集考勤记录成功: 设备={}, 记录数={}", device.getName(), records.size());
			
		} catch (Exception e) {
			logger.error("从设备采集考勤记录失败: 设备=" + device.getName(), e);
		}
		
		return records;
	}

	/**
	 * 批量采集所有设备的考勤记录
	 */
	public List<AttendanceRecord> collectAllDeviceRecords(List<AttendanceDevice> devices) {
		List<AttendanceRecord> allRecords = new ArrayList<>();
		
		for (AttendanceDevice device : devices) {
			if (device.getEnabled() && "ONLINE".equals(device.getStatus())) {
				List<AttendanceRecord> records = collectRecordsFromDevice(device);
				allRecords.addAll(records);
			}
		}
		
		return allRecords;
	}

	/**
	 * 转换原始记录为系统记录
	 */
	private AttendanceRecord convertToAttendanceRecord(RawAttendanceRecord rawRecord, AttendanceDevice device) {
		try {
			AttendanceRecord record = new AttendanceRecord();
			
			record.setEmployeeId(rawRecord.getEmployeeId());
			record.setDeviceId(device.getId());
			record.setPunchTime(rawRecord.getPunchTime());
			record.setPunchType(convertPunchType(rawRecord.getPunchType()));
			record.setVerifyMode(convertVerifyMode(rawRecord.getVerifyMode()));
			record.setSyncStatus("PENDING");
			record.setOriginalRecordId(rawRecord.getRecordId());
			
			return record;
		} catch (Exception e) {
			logger.error("转换考勤记录失败", e);
			return null;
		}
	}

	/**
	 * 转换打卡类型
	 */
	private String convertPunchType(int punchType) {
		switch (punchType) {
			case 0: return "IN";        // 上班
			case 1: return "OUT";       // 下班
			case 2: return "BREAK_OUT"; // 外出
			case 3: return "BREAK_IN";  // 返回
			case 4: return "OVERTIME_IN"; // 加班开始
			case 5: return "OVERTIME_OUT"; // 加班结束
			default: return "UNKNOWN";
		}
	}

	/**
	 * 转换验证方式
	 */
	private String convertVerifyMode(int verifyMode) {
		switch (verifyMode) {
			case 1: return "FINGERPRINT"; // 指纹
			case 2: return "FACE";        // 人脸
			case 3: return "CARD";        // 刷卡
			case 4: return "PASSWORD";    // 密码
			case 5: return "PALM";        // 掌纹
			default: return "UNKNOWN";
		}
	}

	/**
	 * 过滤重复记录
	 */
	public List<AttendanceRecord> filterDuplicateRecords(List<AttendanceRecord> records, 
			List<AttendanceRecord> existingRecords) {
		List<AttendanceRecord> filteredRecords = new ArrayList<>();
		
		for (AttendanceRecord record : records) {
			boolean isDuplicate = false;
			
			for (AttendanceRecord existing : existingRecords) {
				if (isDuplicateRecord(record, existing)) {
					isDuplicate = true;
					break;
				}
			}
			
			if (!isDuplicate) {
				filteredRecords.add(record);
			}
		}
		
		return filteredRecords;
	}

	/**
	 * 检查是否为重复记录
	 */
	private boolean isDuplicateRecord(AttendanceRecord record1, AttendanceRecord record2) {
		if (record1.getOriginalRecordId() != null && record2.getOriginalRecordId() != null) {
			return record1.getOriginalRecordId().equals(record2.getOriginalRecordId());
		}
		
		// 如果没有原始记录ID，则通过员工ID、设备ID和打卡时间判断
		return record1.getEmployeeId().equals(record2.getEmployeeId()) &&
			   record1.getDeviceId().equals(record2.getDeviceId()) &&
			   Math.abs(record1.getPunchTime().getTime() - record2.getPunchTime().getTime()) < 60000; // 1分钟内
	}

	/**
	 * 验证考勤记录数据
	 */
	public boolean validateAttendanceRecord(AttendanceRecord record) {
		if (record.getEmployeeId() == null || record.getEmployeeId().trim().isEmpty()) {
			logger.warn("考勤记录员工ID为空");
			return false;
		}
		
		if (record.getDeviceId() == null || record.getDeviceId().trim().isEmpty()) {
			logger.warn("考勤记录设备ID为空");
			return false;
		}
		
		if (record.getPunchTime() == null) {
			logger.warn("考勤记录打卡时间为空");
			return false;
		}
		
		// 检查打卡时间是否合理（不能是未来时间，不能太久远）
		Date now = new Date();
		if (record.getPunchTime().after(now)) {
			logger.warn("考勤记录打卡时间不能是未来时间");
			return false;
		}
		
		// 不能超过1年前的记录
		long oneYearAgo = now.getTime() - (365L * 24 * 60 * 60 * 1000);
		if (record.getPunchTime().getTime() < oneYearAgo) {
			logger.warn("考勤记录打卡时间过于久远");
			return false;
		}
		
		return true;
	}

	/**
	 * 原始考勤记录类
	 */
	public static class RawAttendanceRecord {
		private String recordId;
		private String employeeId;
		private Date punchTime;
		private int punchType;
		private int verifyMode;
		private String deviceSN;

		public String getRecordId() {
			return recordId;
		}

		public void setRecordId(String recordId) {
			this.recordId = recordId;
		}

		public String getEmployeeId() {
			return employeeId;
		}

		public void setEmployeeId(String employeeId) {
			this.employeeId = employeeId;
		}

		public Date getPunchTime() {
			return punchTime;
		}

		public void setPunchTime(Date punchTime) {
			this.punchTime = punchTime;
		}

		public int getPunchType() {
			return punchType;
		}

		public void setPunchType(int punchType) {
			this.punchType = punchType;
		}

		public int getVerifyMode() {
			return verifyMode;
		}

		public void setVerifyMode(int verifyMode) {
			this.verifyMode = verifyMode;
		}

		public String getDeviceSN() {
			return deviceSN;
		}

		public void setDeviceSN(String deviceSN) {
			this.deviceSN = deviceSN;
		}
	}
}

